// Copyright (c) 2025 Yao Yu
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.

use alloc::sync::Arc;
use core::cell::Ref;
use crate::{prelude::*, thread::{Thread, ThreadLocal}};
use ostd::mm::{Fallible, Vaddr, VmReader, VmSpace};

pub struct Context<'a> {
    thread: &'a Thread,
    thread_local: &'a ThreadLocal,
    // TODO: to add more fields for context
}

impl<'a> Context<'a> {
    pub fn new(thread: &'a Thread, thread_local: &'a ThreadLocal) -> Self {
        Self { 
            thread,
            thread_local,
        }
    }
    pub fn thread(&self) -> &'a Thread {
        self.thread
    }
    pub fn user_space(&self) -> CurrentUserSpace {
        // let ret = self.thread.vm_space().unwrap();
        // ret.as_ref()
        let ret = self.thread_local
        .vm_space()
        .borrow();
        
        CurrentUserSpace(ret)
    }
}

pub struct CurrentUserSpace<'a>(Ref<'a, Option<Arc<VmSpace>>>);

impl<'a> CurrentUserSpace<'a> {
    pub fn root_vmar(&self) -> &VmSpace {
        self.0
        .as_ref()
        .unwrap()
    }

    pub fn reader(&self, vaddr: Vaddr, len: usize) -> Result<VmReader<'_, Fallible>> {
        Ok(
            self.root_vmar()
            .reader(vaddr, len)?
        )
    }
}
